#ifndef GLOBALVARIABLES_H_INCLUDED
#define GLOBALVARIABLES_H_INCLUDED

#include "Atomic.h"
#include "Iterator.h"
#include <limits>
#include <float.h>

namespace CEngine {

namespace VariableManager {

    enum VariableType{
        BOOL,   ///Variable can be true or false.
        STRING, ///Variable is a string. ex: "This is text."
        FLOAT,  ///Variable is a 64-bit floating point number.
        INT,    ///Variable is a 64-bit signed number (default limits are -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807).
        UINT    ///Variable is a 64-bit unsigned number (default limits are 0 to 18,446,744,073,709,551,615).
    };

    ///Internal structure for stored variables.
    struct VariableInternal {
        union {
            CHAR*   string;
            D64     fNumber;
            I64     number;
            U64     uNumber;
            bool    toggle;
        } data;
        union {
            D64     fNumber;
            I64     number;
            U64     uNumber;
        } minValue;
        union {
            D64     fNumber;
            I64     number;
            U64     uNumber;
        } maxValue;
        VariableType type;
    };

    ///Creates a bool variable with a given name and default value.
    void
    CreateVariable(const CHAR* name, bool defaultValue = true);

    ///Creates a string variable with a given name, default string, and max length.
    void
    CreateVariable(const CHAR* name, CHAR* defaultValue = NULL, U32 maxLength = 254);

    ///Creates a float variable with a given name, default value, min value, and max value.
    void
    CreateVariable(const CHAR* name, D64 defaultValue = 0.0, D64 minValue = DBL_MIN, D64 maxValue = DBL_MAX);

    ///Creates a int variable with a given name, default value, min value, and max value.
    ///The variable's type will be guessed based on the set limits if type isn't set to either INT or UINT.
    void
    CreateVariable(const CHAR* name, I64 defaultValue = 0, I64 minValue = LLONG_MIN, I64 maxValue = LLONG_MIN, VariableType type = (VariableType)0);

    ///Creates a uint variable with a given name, default value, min value, and max value.
    ///The variable's type will be guessed based on the set limits if type isn't set to either INT or UINT.
    void
    CreateVariable(const CHAR* name, U64 defaultValue = 0, U64 minValue = 0, U64 maxValue = ULLONG_MAX, VariableType type = (VariableType)0);

    const Iterator<VariableInternal>
    getVariable(const CHAR* name);

    void
    RemoveVariable(const CHAR* name);
}

}

#endif // GLOBALVARIABLES_H_INCLUDED
